#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 赋值
void test1()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	vector<int> v2(v1);

	for (size_t i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	for (size_t i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << " ";
	}
	cout << endl;

	vector<int> v3;
	v3.push_back(10);
	v3.push_back(20);
	v3.push_back(30);
	v3.push_back(40);
	v1 = v3;
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

// 遍历
void test2()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	for (size_t i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	// 迭代器
	vector<int>::iterator it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;

	// 范围for
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

// 三种迭代器
void test3()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	// 普通正向迭代器 可读可写
	vector<int>::iterator it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
	// const正向迭代器 可读不可写 一般是函数传参时参数是const类型才会用到
	vector<int>::const_iterator it2 = v1.begin();
	while (it2 != v1.end())
	{
		cout << *it2 << " ";
		it2++;
	}
	cout << endl;
	// 普通反向向迭代器 可读可写
	vector<int>::reverse_iterator it3 = v1.rbegin();
	while (it3 != v1.rend())
	{
		cout << *it3 << " ";
		it3++;
	}
	cout << endl;
	// const反向向迭代器 可读不可写
	vector<int>::const_reverse_iterator it4 = v1.rbegin();
	while (it4 != v1.rend())
	{
		cout << *it4 << " ";
		it4++;
	}
	cout << endl;
}

// Windows环境下容量是1.5倍增加，Linux环境下容量是2倍增加
// 1.5倍增容效率低，因为每次增容都有代价
// 2倍增容效率高，但是更浪费空间
void test4()
{
	vector<int> v;
	size_t sz = v.capacity();
	cout << "begin:" << sz << endl;
	for (size_t i = 0; i < 100; i++)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "changed:" << sz << endl;
		}
	}
	// reserve可以直接改变容量，不用频繁增容
	// v.reserve(100);
}

void test5()
{
	// 用迭代器插入
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	v1.insert(v1.begin(), 0); // 相当于头插
	// 范围for
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	v1.erase(v1.begin()); // 相当于头删
	// 范围for
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

// <algorithm>的算法
void test6()
{
	//在vevtor删除5
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(210);
	v1.push_back(30);
	v1.push_back(42);
	v1.push_back(5);
	// vector没有find的接口，所以我们要用到的find找到5
	//前两个参数是迭代器，代表需要查找的STL的范围，最后是要查找的数据
	vector<int>::iterator pos = find(v1.begin(),v1.end(),5);
	if(pos != v1.end()) v1.erase(pos);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	sort(v1.begin(),v1.end());
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

//迭代器失效：增容
void test7(){
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

	// 迭代器
	vector<int>::iterator it1 = v1.begin();

	//在这里重新插入可能会迭代器失效，因为可能会增容
	//STL的增容是申请新空间，释放旧空间，就说明it1指向的已经不是原来的空间了
	v1.push_back(6);
	v1.push_back(7);

	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
}

//迭代器失效：删除
void test8(){
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

	vector<int>::iterator it1 = v1.begin();

	//删除it之后，it就失效了，it的位置不对了
	//把2删掉后，it指向的变为3了，之后++，变成指向4，漏掉了3
	//VS下报错，gcc不报错
	while (it1 != v1.end())
	{
		//删除空间的偶数
		if(*it1 % 2 == 0){
			v1.erase(it1);
		}
		++it1;
	}

}

int main()
{
	// test1();
	// test2();
	// test3();
	// test4();
	// test5();
	//test6();
	//test7();
	test8();
	return 0;
}